package com.xiaoyu.code;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;

import java.beans.PropertyVetoException;
import java.util.*;

/**
 * 初始化创建数据源
 *
 * @author zhour
 */
public class DynamicDataSourceManager {
    Logger logger = Logger.getLogger(DynamicDataSourceManager.class);
    @Autowired
    private IDynamicDataSourceDao dynamicDataSourceDao;
    //
    private Map<Integer, ComboPooledDataSource> dataSourcePoolMap = new HashMap<Integer, ComboPooledDataSource>();

    /**
     * 初始化加载创建数据源连接池
     */
    public void init() {
        logger.info("-------------->开始初始化加载创建动态数据源...");
        //获取所有数据源配置信息
        List<AdminDataSource> dataSourceList = dynamicDataSourceDao.select(new AdminDataSource());
        for (AdminDataSource adminDataSource : dataSourceList) {
            //
            createDataSourcePool(adminDataSource);
        }
        logger.info("-------------->初始化加载创建动态数据源完毕，加载数：" + dataSourceList.size());
    }

    /**
     * 创建数据源连接池
     *
     * @param adminDataSource
     */
    public void createDataSourcePool(AdminDataSource adminDataSource) {
        ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
        try {
            comboPooledDataSource.setDriverClass(adminDataSource.getDriverClass());
            comboPooledDataSource.setJdbcUrl(adminDataSource.getUrl());
            comboPooledDataSource.setUser(adminDataSource.getUser());
            comboPooledDataSource.setPassword(adminDataSource.getPassword());
            //
            comboPooledDataSource.setInitialPoolSize(1);
            comboPooledDataSource.setMinPoolSize(0);
            comboPooledDataSource.setMaxPoolSize(5);
            comboPooledDataSource.setAcquireIncrement(2);
            comboPooledDataSource.setMaxIdleTime(10);
            comboPooledDataSource.setMaxStatements(0);
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }
        this.dataSourcePoolMap.put(adminDataSource.getId(), comboPooledDataSource);
    }

    /**
     * 获取数据源
     *
     * @param id
     * @return
     */
    public JdbcTemplate getDataSourcePoolBySourceID(int id) throws Exception {
        //
        ComboPooledDataSource comboPooledDataSource = this.dataSourcePoolMap.get(id);
        if (comboPooledDataSource == null) {
            logger.info(String.format("未找到[SourceID=%d]对应的数据源，则从数据库重新获取...", id));
            //未获取到相应的数据源，则从数据库重新获取，来创建新的数据源连接池
            AdminDataSource adminDataSource1 = new AdminDataSource();
            adminDataSource1.setId(id);
            AdminDataSource adminDataSource = dynamicDataSourceDao.selectOne(adminDataSource1);
            if (adminDataSource == null) {
                logger.info(String.format("从数据库重新获取，未找到[SourceID=%d]对应的数据源", id));
                throw new Exception("未获取到匹配的动态数据源[ID=" + id + "]");
            } else {
                //add
                createDataSourcePool(adminDataSource);
                //get
                comboPooledDataSource = this.dataSourcePoolMap.get(id);
            }

        } else {
            logger.info(String.format("已找到[SourceID=%d]对应的数据源!", id));
        }
        //
        JdbcTemplate jdbcTempleDynamic = new JdbcTemplate(comboPooledDataSource);
        //
        return jdbcTempleDynamic;
    }

    /**
     * 关闭所有数据源连接池
     */
    public void close() {
        Set<Integer> key = dataSourcePoolMap.keySet();
        for (Iterator it = key.iterator(); it.hasNext(); ) {
            ComboPooledDataSource comboPooledDataSource = dataSourcePoolMap.get(it.next());
            try {
                comboPooledDataSource.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}